package com.qf.events.listeners;

import com.qf.events.UserLoginEvent;
import com.qf.mappers.LogininforMapper;
import com.qf.mappers.UserOnlineMapper;
import com.qf.pojo.BaseUser;
import com.qf.pojo.Logininfor;
import com.qf.pojo.User;
import com.qf.pojo.UserOnline;
import com.qf.service.UserService;
import com.qf.utils.RequestUtil;
import com.qf.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/*
杨威
2022/1/1
13:55
*/
@Component
public class UserLoginListener {
    @Autowired
    UserService userService;
    @Autowired
    UserOnlineMapper userOnlineMapper;
    @Autowired
    LogininforMapper logininforMapper;

    @EventListener
    public void upDateUserInfo(AuthenticationSuccessEvent loginEvent) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        User user = SecurityUtils.getUser();
        //security发布登录成功的事件 开了一个新线程 所有工具类获取不到user了
        //要从事件里面获取
        BaseUser baseUser = (BaseUser) loginEvent.getAuthentication().getPrincipal();
        User user = new User();
        user.setUsername(baseUser.getUsername());
        user.setUId(baseUser.getUserId());
        //异步大部分都会开一个子线程 不耗费主线程的时间
        //也是一个异步（异步方法） 内部自带线程池
        //在方法上面加异步注解 会导致整个方法都是异步 而request请求的是主线程 需要在主线程才能获取到
        CompletableFuture.runAsync(() -> {
            user.setCurrentLogin(new Date());
            //获取当前用户的ip
            String ip = RequestUtil.getRemoteHost(request);
            user.setCurrentLoginIp(ip);
            userService.updateUserLogin(user);
        });
    }

    @EventListener
    public void upDateUserOnline(AuthenticationSuccessEvent loginEvent) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        User user = SecurityUtils.getUser();
        BaseUser baseUser = (BaseUser) loginEvent.getAuthentication().getPrincipal();
        User user = new User();
        user.setUsername(baseUser.getUsername());
        user.setUId(baseUser.getUserId());
        CompletableFuture.runAsync(() -> {
            try {
                //存放了是请求的系统和软件信息
                Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);
                UserOnline userOnline = new UserOnline();
                userOnline.setSessionId(request.getSession().getId());
                userOnline.setLoginName(user.getUsername());
                //获取当前用户的ip
                String ip = RequestUtil.getRemoteHost(request);
                userOnline.setIpaddr(ip);
//                userOnline.setLoginLocation(RequestUtil.getLocationByIp(ip));
                userOnline.setBrowser(osAndBrowserInfo.get("browser"));
                userOnline.setOs(osAndBrowserInfo.get("os"));
                userOnline.setStatus("1");
                userOnline.setStartTimestamp(new Date());
                userOnline.setExpireTime(30L);

                UserOnline userOnline1 = userOnlineMapper.selectByLoginName(user.getUsername());
                if (userOnline1 == null) {
                    userOnlineMapper.insertUserOnline(userOnline);
                } else {
                    userOnlineMapper.updateUserOnline(userOnline);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @EventListener
    //登录成功写日志
    public void onLoginLog(AuthenticationSuccessEvent loginEvent) {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        User user = SecurityUtils.getUser();
        BaseUser baseUser = (BaseUser) loginEvent.getAuthentication().getPrincipal();
        User user = new User();
        user.setUsername(baseUser.getUsername());
        user.setUId(baseUser.getUserId());
        CompletableFuture.runAsync(() -> {
            Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);
            Logininfor logininfor = new Logininfor();
            logininfor.setLoginName(user.getUsername());
            //获取当前用户的ip
            String ip = RequestUtil.getRemoteHost(request);
            logininfor.setIpaddr(ip);
            logininfor.setBrowser(osAndBrowserInfo.get("browser"));
            logininfor.setOs(osAndBrowserInfo.get("os"));
            if (user != null) {
                logininfor.setStatus("0");
                logininfor.setMsg("登录成功");
            } else {
                logininfor.setStatus("1");
                logininfor.setMsg("登录失败");
            }
            logininfor.setLoginTime(new Date());
            logininforMapper.insert(logininfor);

        });
    }


    @EventListener
    //登录失败写日志
    public void onLoginFail(AbstractAuthenticationFailureEvent loginEvent) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        User user = SecurityUtils.getUser();
        String principal = (String) loginEvent.getAuthentication().getPrincipal();
        System.out.println("principal = " + principal);
        User user = new User();
        user.setUsername(principal);
        CompletableFuture.runAsync(() -> {
            Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);
            Logininfor logininfor = new Logininfor();
            logininfor.setLoginName(user.getUsername());
            //获取当前用户的ip
            String ip = RequestUtil.getRemoteHost(request);
            logininfor.setIpaddr(ip);
            logininfor.setBrowser(osAndBrowserInfo.get("browser"));
            logininfor.setOs(osAndBrowserInfo.get("os"));

            logininfor.setStatus("1");
            logininfor.setMsg("登录失败");

            logininfor.setLoginTime(new Date());
            logininforMapper.insert(logininfor);

        });
    }
}
